home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n01.arc / INT9.PAS < prev    next >
Pascal/Delphi Source File  |  1990-12-11  |  7KB  |  172 lines

  1.  
  2. {******************************************************************************
  3.  *                                                                            *
  4.  *                   PC MAGAZINE'S INTERRUPT 9H READER                        *
  5.  *                Copyright (c) 1990 Ziff Communications Co.                  *
  6.  *              portions Copyright (c) TurboPower Software 1987               *
  7.  *                      written by Barry Simon                                *
  8.  *                                                                            *
  9.  *****************************************************************************}
  10.  
  11. USES
  12.   Dos, CRT;
  13.  
  14. {the next type and the inline code in ChainInt are from Turbo Power Software's
  15.        Turbo Professional package and are used with permission}
  16.  
  17. TYPE
  18.   IntRegisters =
  19.     RECORD
  20.       BP, ES, DS, DI, SI, DX, CX, BX, AX, IP, CS, Flags : Word;
  21.     END;
  22.  
  23. VAR
  24.   CurH, CurL : Byte;
  25.   Regs : Registers;
  26.  
  27.   PROCEDURE HideCursor;
  28.   BEGIN
  29.     WITH Regs DO BEGIN
  30.       AH := 3;                    {read cursor info}
  31.       BH := 0;                    {assume page 0}
  32.       intr($10, Regs);
  33.       CurH := CH; CurL := CL;     {save cursor info}
  34.       AH := 1;                    {set Cursor Shape}
  35.       CX := $2000;                {hide cursor}
  36.       intr($10, Regs);
  37.     END;
  38.   END;
  39.  
  40.   PROCEDURE RestoreCursor;
  41.   BEGIN
  42.     WITH Regs DO BEGIN
  43.       CH := CurH; CL := CurL;     {restore cursor info}
  44.       AH := 1;                    {set Cursor Shape}
  45.       intr($10, Regs);
  46.     END;
  47.   END;
  48.  
  49.   PROCEDURE ChainInt(VAR Regs : IntRegisters; JumpAddr : Pointer);
  50.     {Copyright (c) TurboPower Software 1987}
  51.     {-Restores stack, registers from Regs and 'jumps' to JumpAddr}
  52.   INLINE(
  53.          $5B/                     {pop bx          ;BX = Ofs(JumpAddr^)}
  54.          $58/                     {pop ax          ;AX = Seg(JumpAddr^)}
  55.          $5E/                     {pop si          ;SI = Ofs(Regs)}
  56.          $1F/                     {pop ds          ;DS:SI => Regs}
  57.                              {;Change stack so RETF passes control to JumpAddr;
  58.                               restore Flags}
  59.          $87/$5C/$0E/             {xchg bx,[si+14] ;Switch old BX and Ofs(JumpAddr^)}
  60.          $87/$44/$10/             {xchg ax,[si+16] ;Switch old AX and Seg(JumpAddr^)}
  61.          $8B/$54/$16/             {mov  dx,[si+22] ;Old Flags into DX}
  62.          $52/                     {push dx         ;Push altered flags}
  63.          $9D/                     {popf            ;Pop them into place}
  64.          {;Switch stacks -- make SS:SP point to Regs.BP}
  65.          $8C/$DA/                 {mov dx,ds       ;DX = Seg(Regs)}
  66.          $FA/                     {cli             ;Interrupts off}
  67.          $8E/$D2/                 {mov ss,dx       ;Restore SS from DX}
  68.          $89/$F4/                 {mov sp,si       ;Restore SP from SI}
  69.          $FB/                     {sti             ;Interrupts on}
  70.          $5D/                     {pop bp          ;Restore BP}
  71.          $07/                     {pop es          ;Restore ES}
  72.          $1F/                     {pop ds          ;Restore DS}
  73.          $5F/                     {pop di          ;Restore DI}
  74.          $5E/                     {pop si          ;Restore SI}
  75.          $5A/                     {pop dx          ;Restore DX}
  76.          $59/                     {pop cx          ;Restore CX}
  77.          {;BX and AX restored earlier; their places on stack}
  78.          {;now have JumpAddr, which is where return will go}
  79.          $CB);                    {retf            ;Chain to JumpAddr}
  80.  
  81.  
  82. CONST
  83.   HexDigits : ARRAY[0..15] OF Char = '0123456789ABCDEF';
  84.  
  85.   FUNCTION ByteToHex(B : Byte) : STRING;
  86.     {Changes byte to hex string}
  87.   BEGIN
  88.     ByteToHex := HexDigits[B DIV 16]+HexDigits[B MOD 16];
  89.   END;
  90.  
  91. VAR
  92.   oldint9 : Pointer;
  93.   numkeys : Byte;
  94.   scancode : ARRAY[0..127] OF Byte; {more than 1 is needed to handle
  95.                                       keystrokes that produce multiple
  96.                                       int9's}
  97.   x, y, j : Byte;
  98.   int16regs : Registers;
  99.  
  100.   PROCEDURE myint9(BP : Word); interrupt;
  101.   VAR
  102.     Regs : IntRegisters ABSOLUTE BP;
  103.   BEGIN
  104.     IF (numkeys < 128) THEN numkeys := numkeys+1;
  105.     scancode[numkeys] := Port[$60];
  106.     ChainInt(Regs, oldint9);
  107.   END;
  108.  
  109. BEGIN
  110.   textattr := $0E;
  111.   getintvec(9, oldint9);
  112.   setintvec(9, @myint9);
  113.   HideCursor;
  114.   numkeys := 0;
  115.   clrscr;
  116.   gotoXY(1, 1);
  117.   WriteLn('PC Magazine''s Int 9 key reader;   Copyright (c) 1990 Ziff Communications Co. ');
  118.   WriteLn('           Hit <Esc> to Exit                  ');
  119.   WriteLn('   Hex     ASCII       Hex     ASCII       Hex     ASCII       Hex     ASCII   ');
  120.   WriteLn('  ------  -------     ------  -------     ------  -------     ------  -------  ');
  121.   gotoXY(1, 5);
  122.   x := 5;
  123.   WHILE True DO BEGIN
  124.     IF numkeys > 0 THEN BEGIN
  125.       y := whereY;
  126.       IF (((y > 20) AND (scancode[0] <> $E0) AND (scancode[0] <> $FA)
  127.            AND (scancode[0] > $80))
  128.           OR (y > 23)) THEN IF x < 65 THEN BEGIN
  129.           x := x+20;
  130.           y := 5;
  131.         END ELSE BEGIN
  132.           clrscr;
  133.           gotoXY(1, 1);
  134.           WriteLn('PC Magazine''s Int 9 key reader;   Copyright (c) 1990 Ziff Communications Co. ');
  135.           WriteLn('           Hit <Esc> to Exit                  ');
  136.           WriteLn('   Hex     ASCII       Hex     ASCII       Hex     ASCII       Hex     ASCII   ');
  137.           WriteLn('  ------  -------     ------  -------     ------  -------     ------  -------  ');
  138.           gotoXY(1, 5);
  139.           x := 5;
  140.           y := 5;
  141.         END;
  142.       gotoXY(x, y);
  143.       Write(ByteToHex(scancode[1]));
  144.       gotoXY(x+8, y);
  145.       {writeln(scancode[1]:3,'    ',numkeys)}
  146.         {comment in above line and out below line to explore stack; try
  147.           putting on numlock and hitting cursor keys a lot!!}
  148.       WriteLn(scancode[1]:3);
  149.       IF numkeys = 127 THEN WriteLn('Keystack Overflow!!! Program Halted');
  150.       IF (((scancode[1] MOD 128) = 1) OR (numkeys = 127)) THEN BEGIN
  151.         setintvec(9, oldint9);
  152.         WHILE keypressed DO BEGIN
  153.           int16regs.AH := 0;
  154.           intr($16, int16regs);
  155.         END;
  156.         gotoXY(1, 23);
  157.         RestoreCursor;
  158.         Halt;
  159.       END;
  160.       IF ((numkeys = 1) AND (scancode[1] <> $E0) AND (scancode[1] <> $FA)
  161.           AND (scancode[1] > $80)) THEN WriteLn;
  162.       numkeys := numkeys-1;
  163.       FOR j := 0 TO numkeys DO scancode[j] := scancode[j+1];
  164.       WHILE keypressed DO BEGIN
  165.         int16regs.AH := 0;
  166.         intr($16, int16regs);
  167.       END;
  168.     END;
  169.   END;
  170. END.
  171.  
  172.